package com 
{
	import data.GCItemData;
	import flash.utils.Dictionary;
	import com.GCItem;

	/**
	 * Logical component for a player's inventory. The inventory can
	 * be at the ship or it can be a warehouse at a city.
	 */
	public class GCInventory
	{
		/*
		 * These dictionaries are the structures that will actually contain all items
		 * that a player has in a single inventory.
		 * Key: itemId, Value: GCItem
		 */
		private var _inventory:Dictionary;

		/*
		 * Keep track of how much space is currently occupied in this inventory and
		 * maximum allowed capacity.
		 */		
		private var _currentCapacity:int;
		private var _maxCapacity:int;		
		
		/**
		 * This constructor to create an inventory object. Should be called only
		 * at the startup of a game or when a user builds a new warehouse at a city.
		 * 
		 * @param	items
		 * @param	capacity
		 */
		public function GCInventory(inventory:Vector.<GCItem>, currentCapacity:int, maxCapacity:int) 
		{			
			_inventory = new Dictionary();
			
			var item:GCItem;
			for each (item in inventory)
			{
				trace("Added item to GCInventory");
				_inventory[item.itemId] = item;
			}
			
			this._currentCapacity = currentCapacity;
			this._maxCapacity = maxCapacity;
		}
		
		
		//----------------------------------------------------------------------
		//	PUBLIC FUNCTIONS
		//----------------------------------------------------------------------
		
		/**
		 * Adds the given item to the inventory
		 * @param	newItems
		 * @return
		 */
		public function addToInventory(newItem:GCItem):void
		{
			_inventory[newItem.itemId] = newItem;
			_currentCapacity += newItem.quantity;
		}

		/**
		 * Removes the given quantity of the given item from the inventory
		 * Returns 0 if successful and -1 otherwise
		 * @param	itemId
		 * @param	quantity
		 * @return
		 */
		public function removeFromInventory(itemId:int, quantity:int):int
		{
			var item:GCItem = _inventory[itemId] as GCItem;
			
			// Check if the item is in the inventory
			if (item != null)
			{
				// Check if the quantity is within range
				if (quantity > item.quantity || quantity < 0)
				{
					// Invalid number of items to remove
					return -1;
				}
				
				if (item.quantity == quantity)
				{
					// Remove all items
					delete _inventory[itemId];
					_currentCapacity -= quantity;
					return 0;
				}
				else 
				{
					// Remove some of the items
					item.quantity = item.quantity - quantity;
					_currentCapacity -= quantity;
					return 0;
				}
			}
			else 
			{
				// Item doesn't exist in our list
				return -1;
			}
		}
		
		/**
		 * Return a list of the items that are of a particular type.
		 * 
		 * @param 	type
		 * 			The uint type of the goods you want
		 * @return
		 */
		public function getItemsOfType(type:uint):Vector.<GCItem>
		{
			var itemsList:Vector.<GCItem> = new Vector.<GCItem>();
			
			for (var obj:Object in _inventory)
			{
				var id:uint = obj as uint;
				if (GCItemData.getTypeFromId(id) == type)
				{
					itemsList.push(_inventory[id]);
				}
			}
			
			return itemsList;
		}				
		
		/**
		 * Append a particular quantity to the inventory if item type is present, else it will
		 * create a new item.
		 * 
		 * @param	itemId
		 * @param	quantity
		 */
		public function addQuantityToInventory(invItemId:uint, itemId:uint, quantityToAdd:uint):void
		{
			if (_inventory.hasOwnProperty(itemId))
			{
				trace("GCInventory:already there");
				var itemObject:GCItem = _inventory[itemId];
				itemObject.quantity += quantityToAdd;
				_currentCapacity += quantityToAdd;
			}
			else
			{
				trace("GCInventory:add new here");
				return addToInventory(new GCItem(invItemId, itemId, quantityToAdd, GCPlayState.getPlayerId(), GCPlayState.getPlayerName()));
			}
		}
		
		//----------------------------------------------------------------------
		//	GET FUNCTIONS
		//----------------------------------------------------------------------
		
		/**
		  * Function to get a particular type of good based on that
		  * goods item.
		  * 
		  * @param itemId
		  * 	The id of the item to get.
		  * @return
		  * 	The GCItem object for the desired item contained in this
		  * 	invenotry if it exists. Returns null otherwise.
		  */
		public function getItemFromId(itemId:int):GCItem
		{
			return _inventory[itemId];
		}		
		
		public function get currentCapcity():int
		{
			return _currentCapacity;
		}
		
		public function get maxCapacity():int
		{
			return _maxCapacity;
		}
		
		public function get inventory():Dictionary
		{
			return _inventory;
		}
		
		//----------------------------------------------------------------------
		//	SET FUNCTIONS
		//----------------------------------------------------------------------
		
		public function set currentCapcity(newCapcity:int):void
		{
			_currentCapacity = newCapcity;
		}
		
		public function set maxCapacity(newCapcity:int):void
		{
			_maxCapacity = newCapcity;
		}		
		
		/*
		function compare(item1:GCItem, item2:GCItem):Number
		{
			if (item1.itemId < item2.itemId)
				return -1;
			else if (item1.itemId > item2.itemId)
				return 1;
			else 
			{
				if (item1.price < item2.itemId)
					return -1
				else if (item1.price > item2.price)
					return 1;
			}
			return 0;			
		}*/
		
	}
}